﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using HengTong.Model.Db;
using HengTong.Model.Db.System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using TiaoTaoHelper.Wtm.Models;


namespace HengTong.ViewModel._Admin.SysJobPositionVms
{
    public partial class SysJobPositionVm : BaseCRUDVM<SysJobPosition>
    {
        /// <summary>
        /// 角色列表
        /// </summary>
        [Display(Name = "角色")]
        public List<Guid?> SelectedRolesIds { get; set; }
        
        /// <summary>
        /// 组织机构列表
        /// </summary>
        [Display(Name = "组织机构")]
        public List<Guid?> SelectedOrganizationIds { get; set; }

        public SysJobPositionVm()
        {
            SetInclude(x => x.Group);
            SetInclude(x => x.Roles);
            SetInclude(x => x.Organizations);
        }

        protected override void InitVM()
        {
            SelectedRolesIds = Entity?.Roles?.Select(x => (Guid?)x.RoleId).ToList() ?? [];
            SelectedOrganizationIds = Entity?.Organizations?.Select(x => x.OrgId).ToList() ?? [];
        }

        public override async Task DoAddAsync()
        {
            if (string.IsNullOrWhiteSpace(Entity.Code))
            {
                //生成岗位编码
                var group = await DC.Set<SysGroup>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(x => x.ID == Entity.GroupId);
                if (group == null)
                {
                    MSD.AddModelError("Entity.GroupId", "所属部门不存在");
                    return;
                }
                //系统自动生成编码
                var max = DC.Set<SysJobPosition>()
                    .Where(e => e.GroupId == Entity.GroupId)
                    .OrderByDescending(e => e.Step)
                    .Select(e => e.Step)
                    .FirstOrDefault();
                do
                {
                    max += 1;
                    Entity.Code = group.GroupCode + max.ToString("00");
                    var any = DC.Set<SysJobPosition>()
                        .Where(e => e.Code == Entity.Code)
                        .WhereIf(Entity.ID != Guid.Empty, e => e.ID != Entity.ID)
                        .Any();
                    if (!any) break;
                } while (true);
            }
            Entity.Roles = new List<SysJobPositionRole>();
            if (SelectedRolesIds != null)
            {
                foreach (var id in SelectedRolesIds)
                {
                    if(id == null) continue;
                    SysJobPositionRole middle = new SysJobPositionRole
                    {
                        RoleId = id.Value
                    };
                    Entity.Roles.Add(middle);
                }
            }
            if (SelectedOrganizationIds != null)
            {
                Entity.Organizations = new List<SysJobPositionOrg>();
                foreach (var id in SelectedOrganizationIds)
                {
                    SysJobPositionOrg middle = new SysJobPositionOrg
                    {
                        OrgId = id
                    };
                    Entity.Organizations.Add(middle);
                }
            }
            if (Entity is IBasePoco poco)
            {
                poco.CreateBy = Wtm.LoginUserInfo?.ITCode;
                poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                poco.CreateTime = DateTime.Now;
                poco.UpdateTime = DateTime.Now;
            }
            await base.DoAddAsync();
        }

        /// <summary>
        /// 编辑岗位
        /// <br/>需要更新所有关联用户的角色信息
        /// </summary>
        /// <param name="updateAllFields"></param>
        public override async Task DoEditAsync(bool updateAllFields = false)
        {
            var transaction = DC.BeginTransaction();
            try
            {
                //部门禁止修改
                var rawEntity = await DC.Set<SysJobPosition>()
                    .AsNoTracking()
                    .Include(e => e.Roles)
                    .ThenInclude(e => e.Role)
                    .FirstOrDefaultAsync(x => x.ID == Entity.ID);
                if (rawEntity.GroupId != Entity.GroupId)
                {
                    MSD.AddModelError("Entity.GroupId", "岗位所属部门禁止修改");
                    return;
                }

                //如果没有设置岗位编码，则自动生成
                if (string.IsNullOrWhiteSpace(Entity.Code))
                {
                    //生成岗位编码
                    var group = await DC.Set<SysGroup>()
                        .AsNoTracking()
                        .FirstOrDefaultAsync(x => x.ID == Entity.GroupId);
                    if (group == null)
                    {
                        MSD.AddModelError("Entity.GroupId", "所属部门不存在");
                        return;
                    }

                    //系统自动生成编码
                    var max = DC.Set<SysJobPosition>()
                        .Where(e => e.GroupId == Entity.GroupId)
                        .OrderByDescending(e => e.Step)
                        .Select(e => e.Step)
                        .FirstOrDefault();
                    do
                    {
                        max += 1;
                        Entity.Code = group.GroupCode + max.ToString("00");
                        var any = DC.Set<SysJobPosition>()
                            .Where(e => e.Code == Entity.Code)
                            .WhereIf(Entity.ID != Guid.Empty, e => e.ID != Entity.ID)
                            .Any();
                        if (!any) break;
                    } while (true);
                }

                Entity.Roles = new List<SysJobPositionRole>();
                if (SelectedRolesIds != null)
                {
                    // 清除原有角色
                    Entity.Roles = new List<SysJobPositionRole>();
                    foreach (var item in SelectedRolesIds)
                    {
                        if (item == null) continue;
                        SysJobPositionRole middle = new SysJobPositionRole()
                        {
                            RoleId = item.Value
                        };
                        Entity.Roles.Add(middle);
                    }
                }

                if (SelectedOrganizationIds != null)
                {
                    Entity.Organizations = new List<SysJobPositionOrg>();
                    foreach (var item in SelectedOrganizationIds)
                    {
                        SysJobPositionOrg middle = new SysJobPositionOrg()
                        {
                            OrgId = item
                        };
                        Entity.Organizations.Add(middle);
                    }
                }

                if (Entity is IBasePoco poco)
                {
                    poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                    poco.UpdateTime = DateTime.Now;
                }

                await base.DoEditAsync(updateAllFields);
                //如果修改了角色, 找出所有本岗位的人员, 修改角色
                // 判断角色是否修改
                if (rawEntity.Roles.Select(x => x.RoleId).OrderBy(x => x)
                    .SequenceEqual(Entity.Roles.Select(x => x.RoleId).OrderBy(x => x)))
                {
                    await transaction.CommitAsync();
                    return; // 角色未修改
                }

                var users = await DC.Set<SysUserJobPosition>()
                    .AsNoTracking()
                    .Where(x => x.JobPositionId == Entity.ID)
                    .Select(x => x.User)
                    .ToListAsync();
                if (users.Any())
                {
                    //移除原有角色
                    var roleCodes = rawEntity.Roles.Select(x => x.Role.RoleCode).ToList();
                    foreach (var user in users)
                    {
                        // 删除用户的原有角色
                        await DC.Set<FrameworkUserRole>()
                            .Where(x => x.UserCode == user.ITCode && roleCodes.Contains(x.RoleCode))
                            .ExecuteDeleteAsync();
                        // 添加新的角色
                        foreach (var item in Entity.Roles)
                        {
                            var role = await DC.Set<FrameworkRole>()
                                .AsNoTracking()
                                .FirstOrDefaultAsync(x => x.ID == item.RoleId);
                            if (role != null)
                            {
                                FrameworkUserRole userRole = new FrameworkUserRole
                                {
                                    UserCode = user.ITCode,
                                    RoleCode = role.RoleCode,
                                    CreateBy = Wtm.LoginUserInfo?.ITCode,
                                    CreateTime = DateTime.Now,
                                    UpdateBy = Wtm.LoginUserInfo?.ITCode,
                                    UpdateTime = DateTime.Now
                                };
                                await DC.Set<FrameworkUserRole>().AddAsync(userRole);
                            }
                            else
                            {
                                MSD.AddModelError("SelectedRolesIds", $"角色 {item.RoleId} 不存在");
                            }
                        }
                    }

                    await DC.SaveChangesAsync();
                }

                await transaction.CommitAsync();
            }
            catch (Exception e)
            {
                // 回滚事务
                await transaction.RollbackAsync();
                var scope = Wtm.ServiceProvider.CreateScope();
                var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysJobPositionVm>>();
                logger.LogError(e, "编辑岗位时发生异常");
            }
            finally
            {
                await transaction.DisposeAsync();
            }
        }
        
        public async Task ApproveAsync(bool upAllFields = false)
        {
            DC = Wtm.CreateDC();
            var transaction = DC.BeginTransaction();
            try
            {
                await base.DoEditAsync(upAllFields);
                if (MSD.IsValid)
                {
                    await ContinueWorkflowAsync(ActionName, Remark);
                    await transaction.CommitAsync();
                }
                else
                {
                    await transaction.RollbackAsync();
                }
            }
            catch (Exception e)
            {
                // 回滚事务
                await transaction.RollbackAsync();
                MSD.AddModelError(" ", $"审批操作异常: {e.Message}");
            }
            finally
            {
                await transaction.DisposeAsync();
            }
        }

        public override void DoDelete()
        {
            base.DoDelete();
        }
    }
}
